package com.gpf.serverImpl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.gpf.common.RequiredLog;
import com.gpf.dao.SysUserDao;
import com.gpf.dao.SysUserRoleDao;
import com.gpf.exception.ServiceException;
import com.gpf.pojo.PageObject;
import com.gpf.pojo.SysUser;
import com.gpf.pojo.SysUserDept;
import com.gpf.server.SysUserService;

import io.micrometer.core.instrument.util.StringUtils;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {
	@Autowired
	private SysUserDao sysUserDao;
	@Autowired
	private SysUserRoleDao sysUserRoleDao;
	@RequiredLog("查询用户")
	@Override
	public PageObject<SysUserDept> findPageObjects(String username,Integer pageCurrent) {
		//1.对参数进行校验
		if(pageCurrent==null||pageCurrent<1)
			throw new IllegalArgumentException("当前页码值无效");
		//2.查询总记录数并进行校验
		Long rowCount=sysUserDao.getRowCount(username);
		if(rowCount==0)
			throw new ServiceException("没有找到对应记录");
		//3.查询当前页记录
		int pageSize=2;
		int startIndex=(pageCurrent-1)*pageSize;
		List<SysUserDept> records=sysUserDao.findPageObjects(username,startIndex, pageSize);
		//4.对查询结果进行封装并返回
		return new PageObject<>(pageCurrent, pageSize, rowCount, records);
	}
	@RequiredLog
	@Override
	public int validById(Integer id,Integer valid) {
		//1.合法性验证
		if(id==null||id<=0)
			throw new ServiceException("参数不合法,id="+id);
		if(valid==null||(valid!=1&&valid!=0))
			throw new ServiceException("参数不合法,valid="+valid);
		//2.执行禁用或启用操作(admin为后续登陆用户）
		int rows=sysUserDao.validById(id, valid,"admin");
		//3.判定结果,并返回
		if(rows==0)
			throw new ServiceException("此记录可能已经不存在");
		return rows;
	}
	@Transactional(readOnly = false,rollbackFor = Throwable.class,timeout = -1,isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRES_NEW)
	@Override
	public int saveObject(SysUser entity, Integer[] roleIds) {
		long start=System.currentTimeMillis();
		log.info("start:"+start);
		//1.参数校验
		if(entity==null)
			throw new IllegalArgumentException("保存对象不能为空");
		if(StringUtils.isEmpty(entity.getUsername()))
			throw new IllegalArgumentException("用户名不能为空");
		if(StringUtils.isEmpty(entity.getPassword()))
			throw new IllegalArgumentException("密码不能为空");
		if(roleIds==null || roleIds.length==0)
			throw new IllegalArgumentException("至少要为用户分配角色");
		//2.保存用户自身信息
		//2.1对密码进行加密
		String source=entity.getPassword();
		String salt=UUID.randomUUID().toString();
		SimpleHash sh=new SimpleHash(//Shiro框架
				"MD5",//algorithmName 算法
				source,//原密码
				salt, //盐值
				1);//hashIterations表示加密次数
		entity.setSalt(salt);
		entity.setPassword(sh.toHex());
		int rows=sysUserDao.insertObject(entity);
		//3.保存用户角色关系数据
		sysUserRoleDao.insertObjects(entity.getId(), roleIds);
		long end=System.currentTimeMillis();
		log.info("end:"+end);
		log.info("total time :"+(end-start));
		//4.返回结果
		return rows;
	}
	@Override
	public Map<String, Object> findObjectById(Integer userId) {
		//1.合法性验证
		if(userId==null||userId<=0)throw new IllegalArgumentException("参数数据不合法,userId="+userId);
		//2.业务查询
		SysUserDept user=sysUserDao.findObjectById(userId);
		if(user==null)throw new ServiceException("此用户已经不存在");
		List<Integer> roleIds=sysUserRoleDao.findRoleIdsByUserId(userId);
		//3.数据封装
		Map<String,Object> map=new HashMap<>();
		map.put("user", user);
		map.put("roleIds", roleIds);
		return map;
	}
	@Override
	public int updateObject(SysUser entity,Integer[] roleIds) {
		//1.参数有效性验证
		if(entity==null) throw new IllegalArgumentException("保存对象不能为空");
		if(StringUtils.isEmpty(entity.getUsername())) throw new IllegalArgumentException("用户名不能为空");
		if(roleIds==null||roleIds.length==0) throw new IllegalArgumentException("必须为其指定角色");
		//其它验证自己实现，例如用户名已经存在，密码长度，...
		//2.更新用户自身信息
		int rows=sysUserDao.updateObject(entity);
		//3.保存用户与角色关系数据
		sysUserRoleDao.deleteObjectsByUserId(entity.getId());
		sysUserRoleDao.insertObjects(entity.getId(),roleIds);
		//4.返回结果
		return rows;
	}     
	@Override
	public int updatePassword(String password, String newPassword,String cfgPassword) {
		//1.判定新密码与密码确认是否相同
		if(StringUtils.isEmpty(newPassword))throw new IllegalArgumentException("新密码不能为空");
		if(StringUtils.isEmpty(cfgPassword))throw new IllegalArgumentException("确认密码不能为空");
		if(!newPassword.equals(cfgPassword))throw new IllegalArgumentException("两次输入的密码不相等");
		//2.判定原密码是否正确
		if(StringUtils.isEmpty(password))throw new IllegalArgumentException("原密码不能为空");
		//获取登陆用户
		SysUser user=(SysUser)SecurityUtils.getSubject().getPrincipal();
		SimpleHash sh=new SimpleHash("MD5",password, user.getSalt(), 1);
		if(!user.getPassword().equals(sh.toHex()))throw new IllegalArgumentException("原密码不正确");
		//3.对新密码进行加密
		String salt=UUID.randomUUID().toString();
		sh=new SimpleHash("MD5",newPassword,salt, 1);
		//4.将新密码加密以后的结果更新到数据库
		int rows=sysUserDao.updatePassword(sh.toHex(), salt,user.getId());
		if(rows==0)throw new ServiceException("修改失败");
		return rows;
	}
}
